/*
    Aufgabe 3) Rekursion - Blumenmuster mit Kreisbögen
*/
public class Aufgabe3 {

    // -2, -1, 1, 2 are standardized values for transformation vectors
    private static int[] transform(int direction) {
        int sign = (int) Math.signum(direction);

        if (direction % 2 == 0) {
            // direction divisible by 2 => Y axis is invariant
            // because the angles for arcs with offset x value are simple
            // [either (90, -90) or (-90, 90)] we directly compute
            // (-angle * sign, angle * sign)
            return new int[] {
                    sign, 0,
                    sign * -90, sign * 90
            };
        } else {
            // direction indivisible by 2 => X axis is invariant
            // because the angles for arcs with offset y value are more
            // complicated [either (180, 0) or (0, -180)], coefficients
            // are computed
            int co1 = direction < 0 ? 180 : 0;
            int co2 = direction < 0 ? 0 : 180;
            return new int[] {
                    0, sign,
                    sign * co1, sign * co2
            };
        }
    }
    
    private static void drawArcPattern(int x, int y, int radius) {
        if (radius < 8) return;

        // for testing purposes, sleep
        try {
            Thread.sleep(20);
        } catch (Exception ignored) {}

        int[] transVec;
        int offsetX, offsetY;

        for (int i : new int[] {-2, -1, 1, 2}) {
            // get parameters
            transVec = transform(i);
            offsetX = x + radius * transVec[0];
            offsetY = y + radius * transVec[1];

            // draw arc segment with respect to current transformation vector
            StdDraw.arc(
                    offsetX,
                    offsetY,
                    radius,
                    transVec[2],
                    transVec[3]
            );

            // ZUSATZFRAGE 3 relevanter code
            // if (i == -2 || i == 1)
            // subsequent recursive call
            drawArcPattern(offsetX, offsetY, radius / 2);
        }
    }
    
    public static void main(String[] args) {
        // StdDraw parameters
        int w = 512, h = 512;
        int scale = w / 2;
        StdDraw.setCanvasSize(w, h);
        StdDraw.setScale(-scale, scale);
        //StdDraw.enableDoubleBuffering();

        // root call to drawArcPattern
        drawArcPattern(0, 0, scale / 2);
    }

// ZUSATZFRAGE 1
/*
    wir betrachten drawArcPattern (dAP):
    - der eigene aufruf sollte mitgezählt werden
    - jeder aufruf innerhalb dAP erzeugt 4 weitere subsequente aufrufe, wobei
      sich für subsequente aufrufe der radius halbiert
    - im base case werden keine weiteren subsequenten aufrufe mehr getätigt

    sei r der radius
    sei s(r) = |dAP(r)|, daher die menge an aufrufen von dAP mit radius r

    dann ist s(r):

        s(r) = 1 + 4 * s(r / 2) mit r >= 8
        s(r) = 1                mit r <  8

    mit einem startwert in der rekursion von dAP mit r = 512 / 2 kommen wir
    somit auf:

        s(256) = 1 + 4 * s(128)                              // expand s(128)
               = 1 + 4 * (1 + 4 * s(64))                     // multiply terms in brackets
               = 1 + 4 + 4^2 * s(64)                         // expand s(64)
               = 1 + 4^1 + 4^2 + 4^3 * s(16)                 // rewrite terms 4^1 + ... + 4^2 as sum
               = 1 + sum(i from 1 to 2, 4^i) + 4^3 * s(16)   // expand s(16)
               = 1 + sum(i from 1 to 3, 4^i) + 4^4 * s(8)    // expand s(8)
               = 1 + sum(i from 1 to 4, 4^i) + 4^5 * s(4)    // expand s(4)
               = 1 + sum(i from 1 to 4, 4^i) + 4^5 * 1       // include remaining term s^5 in sum
               = 1 + sum(i from 1 to 5, 4^i)

               = 1 + 4 + 4^2 + 4^3 + 4^4 + 4^5
               = 1365 aufrufe
*/

// ZUSATZFRAGE 2
/*
    wenn die auflösungsgrenze anders als r < 8 gewählt wird, verschieben sich
    dementsprechend die rekursionsgrenzen für subsequente aufrufe:

    subsequente aufrufe:
        s(r) = 1 + 4 * s(r / 2) mit r >= 8
        s(r) = 1                mit r <  8
    wobei x < 8
*/

// ZUSATZFRAGE 3
/* siehe als relevant gekennzeichneten code in drawArcPattern */
}




